package com.yuda.tools.checkanswer.controller;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSException;
import com.yuda.common.core.web.controller.BaseController;
import com.yuda.common.core.web.domain.AjaxResult;
import com.yuda.common.core.web.page.TableDataInfo;
import com.yuda.tools.checkanswer.Oss.OssMap;
import com.yuda.tools.checkanswer.dto.Province;
import com.yuda.tools.checkanswer.dto.ResultMessage;
import com.yuda.tools.checkanswer.dto.RoadMap;
import com.yuda.tools.checkanswer.service.CheckAnswerService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

@RestController
public class CheckAnswer extends BaseController {

    @Autowired
    private CheckAnswerService checkAnswerService;

    AtomicInteger canRun = new AtomicInteger(0);

    private final ReentrantLock lock = new ReentrantLock();

    @Value("${check.oss_inner_out}")
    private String ossInnerOrOut;

    @Value("${check.answerDbPath}")
    private String answerDbPath;

    @ApiOperation("检查答案")
    @GetMapping("/checkAnswer/{testSession}/{subjectIndex}")
    public String checkAnswer(@PathVariable("testSession") int testSession,
                              @PathVariable("subjectIndex") int subjectIndex) {

        //AnswerHelper.getOssAnswerByType(type) 得到需要下载的区域
        if (canRun.get() == 0) {
            try {
                canRun.set(1);
                return checkAnswerService.checkAnswer(testSession, subjectIndex);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                canRun.set(0);
                //检查是否可以更新位图
               String s =  checkAnswerService.checkCanBeUpdateRoadMap();
               if(s.equals("y")) {
                   checkAnswerService.updateRoadMap();
               }
            }
        } else {
            return "有程序正在运行中";
        }
        return "运行完成";
    }

    @GetMapping("/currentCheckTips")
    public AjaxResult currentCheckTips() {
        String s = checkAnswerService.currentCheckTips();
        if (!StringUtils.isEmpty(s)) {
            return AjaxResult.success(s);
        } else {
            return AjaxResult.error("请联系相关人员，检查科目初始化错误");
        }
    }


    //    @PreAuthorize(hasPermi = "gwoper:label:add")
    @ApiOperation("考试结束无答案")
    @GetMapping("/checkAnswer/list")
    public TableDataInfo list(@RequestParam(value = "searchKey", required = false) String searchKey,
                              @RequestParam(value = "provinceIds", required = false) Integer[] provinceIds,
                              @RequestParam(value = "marked") Integer marked,
                              @RequestParam(value = "handle") Integer handle) {
        startPage();
        List<ResultMessage> list = checkAnswerService.listResultMessage(searchKey, provinceIds, marked, handle);
        return getDataTable(list);
    }

    @ApiOperation("考试中列表")
    @GetMapping("/checkAnswer/listExamIng")
    public TableDataInfo listExamIng(@RequestParam(value = "searchKey", required = false) String searchKey,
                                     @RequestParam(value = "provinceIds", required = false) Integer[] provinceIds) {
        startPage();
        List<ResultMessage> list = checkAnswerService.listResultExaming(searchKey, provinceIds);
        return getDataTable(list);
    }


    @ApiOperation("获取检查答案页面的省份数据")
    @GetMapping("/checkAnswer/listProvince")
    public List<Province> listProvince() {
        return checkAnswerService.listProvince();
    }

    /**
     * 标记以哪个为准
     */
    @ApiOperation("处理从mq取值还是从 log 中取值")
    @PostMapping("/updateAnswerSource")
    public AjaxResult updateAnswerSource(@RequestParam("studentId") String studentId,
                                         @RequestParam("subjectId") String subjectId,
                                         @RequestParam("status") Integer status) {
        lock.lock();
        try {
            int res = checkAnswerService.updateAnswerSource(studentId, subjectId, status);
            if (res == -1) {
                return AjaxResult.error("请先标记为正常");
            }

            if (res == -2) {
                return AjaxResult.error("换过考位不做处理");
            }

            if (res == -3) {
                return AjaxResult.error("找不到日志文件");
            }

            if (res == -4) {
                return AjaxResult.error("mq中找不到记录");
            }
            return toAjax(res);
        } finally {
            lock.unlock();
        }
    }


    //标记答案状态为正常 更新 answer_db_type  down_load_type answer_status 为1
    @ApiOperation("标记答案为正常和反标记")
    @PostMapping("/markAsNormal")
    public AjaxResult markAsNormal(@RequestParam("studentId") String studentId,
                                   @RequestParam("subjectId") String subjectId,
                                   @RequestParam("status") Integer status) {
        if (!(status == 0 || status == 1)) {
            return AjaxResult.error("status 参数不对");
        }

        return toAjax(checkAnswerService.markAsNormal(studentId, subjectId, status));
    }

    //从mq中搜数据
    @ApiOperation("从mq中取值到页面展示")
    @GetMapping("searchFromMq")
    public TableDataInfo searchFromMq(@RequestParam("studentId") String studentId,
                                      @RequestParam("subjectId") String subjectId) {

        return getDataTable(checkAnswerService.searchFromMq(studentId, subjectId));
    }

    @PostMapping("/uploadDb")
    public AjaxResult uploadDb(MultipartFile[] multipartFile) {
        if (multipartFile == null || multipartFile.length == 0) {
            return AjaxResult.error("上传失败");
        }
        OSS oss = OssMap.get("defanswer" + ossInnerOrOut);
        for (MultipartFile file : multipartFile) {
            String originalFilename = file.getOriginalFilename();
            String ext = Objects.requireNonNull(originalFilename).substring(originalFilename.lastIndexOf("."));
            try {
                if (!StringUtils.isEmpty(ext) && ext.equals(".db")) {
                    //根据student_id 查询 pc_no
                    String[] s = originalFilename.split("_");
                    if (s.length == 4) { //答案文件
                        int pcNo = checkAnswerService.getPcNoByStudentId(s[0]);
                        String key = answerDbPath + s[0] + "_" + s[1] + "_" + s[2] + "_" + pcNo + ".db";
                        oss.putObject("defanswer", key, new ByteArrayInputStream(file.getBytes()));
                    }

                    if (s.length == 3) {
                        int pcNo = checkAnswerService.getPcNoByStudentId(s[0]);
                        String key = answerDbPath + s[0] + "_" + s[1] + "_" + pcNo + "_stat.db";
                        oss.putObject("defanswer", key, new ByteArrayInputStream(file.getBytes()));
                    }
                } else {
                    return AjaxResult.error("类型不对");
                }
            } catch (OSSException | ClientException | IOException e) {
                return AjaxResult.error("上传失败");
            }
        }
        return AjaxResult.success("上传成功");
    }

    @GetMapping("/roadMap")
    public AjaxResult roadMap() {

        RoadMap roadMap = checkAnswerService.roadMap();
        return AjaxResult.success(roadMap);
    }
}
